package com.nulldev.util.web.URLUtils.internal.patched;

import java.io.IOException;
import java.net.Proxy;
import java.net.URL;

import com.nulldev.util.JVM.JVM;

public class HttpURLConnection extends sun.net.www.protocol.http.HttpURLConnection {

	public HttpURLConnection(URL u, Proxy p) throws IOException {
		super(u, p);
	}

	/**
	 * Gets the status code from an HTTP response message. For example, in the case
	 * of the following status lines:
	 * 
	 * <PRE>
	 * HTTP/1.0 200 OK
	 * HTTP/1.0 401 Unauthorized
	 * </PRE>
	 * 
	 * It will return 200 and 401 respectively. Returns -1 if no code can be
	 * discerned from the response (i.e., the response is not valid HTTP).
	 * 
	 * @throws IOException if an error occurred connecting to the server.
	 * @return the HTTP Status-Code, or -1
	 */
	@Override
	public int getResponseCode() throws IOException {
		/*
		 * We're got the response code already
		 */
		if (responseCode != -1) {
			return responseCode;
		}

		/*
		 * Ensure that we have connected to the server. Record exception as we need to
		 * re-throw it if there isn't a status line.
		 */
		Exception exc = null;
		try {
			getInputStream();
		} catch (Exception e) {
			JVM.errorln(e);
			exc = e;
		}

		/*
		 * If we can't a status-line then re-throw any exception that getInputStream
		 * threw.
		 */
		String statusLine = getHeaderField(0);
		if (statusLine != null && statusLine.equals("unknown/unknown")) {
			return 200;
		}

		if (statusLine == null) {
			if (exc != null) {
				if (exc instanceof RuntimeException)
					throw (RuntimeException) exc;
				else
					throw (IOException) exc;
			}
			return -1;
		}

		/*
		 * Examine the status-line - should be formatted as per section 6.1 of RFC 2616
		 * :-
		 *
		 * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase
		 *
		 * If status line can't be parsed return -1.
		 */
		if (statusLine.startsWith("HTTP/1.")) {
			int codePos = statusLine.indexOf(' ');
			if (codePos > 0) {

				int phrasePos = statusLine.indexOf(' ', codePos + 1);
				if (phrasePos > 0 && phrasePos < statusLine.length()) {
					responseMessage = statusLine.substring(phrasePos + 1);
				}

				// deviation from RFC 2616 - don't reject status line
				// if SP Reason-Phrase is not included.
				if (phrasePos < 0)
					phrasePos = statusLine.length();

				try {
					responseCode = Integer.parseInt(statusLine.substring(codePos + 1, phrasePos));
					return responseCode;
				} catch (NumberFormatException e) {
				}
			}
		}
		return -1;
	}
}